package com.qdlc.p2p.biz.processor.task;

import java.text.MessageFormat;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qdlc.p2p.biz.processor.event.BorrowValueEvent;
import com.qdlc.p2p.biz.processor.event.CollectionTradeNotifyValueEvent;
import com.qdlc.p2p.biz.processor.event.TppTradeLogValueEvent;
import com.qdlc.p2p.biz.processor.task.collection.TenderTaskProcessor;
import com.qdlc.p2p.biz.service.AccountService;
import com.qdlc.p2p.biz.service.BorrowRepaymentService;
import com.qdlc.p2p.biz.service.BorrowService;
import com.qdlc.p2p.biz.service.BorrowTenderService;
import com.qdlc.p2p.biz.service.TppService;
import com.qdlc.p2p.biz.service.TppTradeService;
import com.qdlc.p2p.common.constant.BorrowStatus;
import com.qdlc.p2p.common.constant.BorrowTenderStatus;
import com.qdlc.p2p.common.constant.SinaConstant;
import com.qdlc.p2p.common.constant.Summary;
import com.qdlc.p2p.common.core.queue.QueueHandlers;
import com.qdlc.p2p.common.core.queue.TaskProcessorException;
import com.qdlc.p2p.common.core.queue.ValueEvent;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.NumberUtil;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dto.Borrow;
import com.qdlc.p2p.dal.dto.BorrowRepayment;
import com.qdlc.p2p.dal.dto.BorrowTender;
import com.qdlc.p2p.dal.dto.Tpp;
import com.qdlc.p2p.dal.dto.TppTradeLog;
import com.qdlc.p2p.dal.model.BorrowModel;
import com.qdlc.p2p.dal.model.TppModel;

/**
 * 代收/代付异步通知
 * 
 * 该类已经过期，请参考{@link AbstractCollectionTradeNotifyTaskProcessor}
 * @author linya 2016-01-12
 */
@Deprecated
public class CollectionTradeNotifyTaskProcessor extends AbstractTaskProcessor {

	private static final Logger logger = Logger.getLogger(CollectionTradeNotifyTaskProcessor.class);
	
	@Resource
	TppTradeService tppTradeService;
	
	@Resource
	TppService tppService;
	
	@Resource
	BorrowTenderService borrowTenderService;
	
	@Resource
	BorrowService borrowService;
	
	@Resource
	AccountDao accountDao;
	
	@Resource
	BorrowRepaymentService borrowRepaymentService;

	@Resource
	AccountService accountService;
	
	@Override
	public boolean supports(ValueEvent event) {
		return event instanceof CollectionTradeNotifyValueEvent;
	}

	@Override
	protected void process0(ValueEvent event) throws TaskProcessorException {
		
		CollectionTradeNotifyValueEvent notifyEvent = (CollectionTradeNotifyValueEvent)event;
		String outTradeNo = notifyEvent.getOutOrderNo();
		String depositStatus = notifyEvent.getDepositStatus();
		
		// 新浪调用, TppTradeLog都会生成
		TppTradeLog tppTradeLog = tppTradeService.find(outTradeNo);
		
		// Tpp在调用新浪接口之后才生成，所以 如果还没生成，我们直接返回err等待生成
		// 自动投标和投标不生成tpp
		Tpp tpp = tppService.getTppByOrdId(outTradeNo);
		if ((tppTradeLog == null) && (tpp != null)) {
			tppTradeLog = tppTradeService.find(tpp.getSubOrdId());
		}

		// 异步回调 订单状态为成功情况
		if (tppTradeLog == null) {
			logger.info(MessageFormat.format("++++ 代收订单号{0}不存在！", outTradeNo));
			return;
		}

		// 判断是否已经成功过
		String sinaStatus = tppTradeLog.getSinaStatus();

		// 订单号已经被处理过了
		if(sinaStatus != null && sinaStatus.contains(depositStatus)){
			logger.info(MessageFormat.format("++++ 订单号{0}状态{1}已经被执行过!", outTradeNo, depositStatus));
			return;
		}
		
		//更新回调后状态
		if(sinaStatus == null){
			tppTradeLog.setSinaStatus(depositStatus);
		}else{
			tppTradeLog.setSinaStatus(sinaStatus + " " + depositStatus);
		}
		
		logger.info(MessageFormat.format("++++ 代收订单号{0}交易类型{1}回调处理{2}", outTradeNo, tppTradeLog.getTradeType(), depositStatus));
		
		// 异步回调 订单状态为已结束情况 
		if (SinaConstant.TRADE_STATUS_FINISHED.equals(depositStatus)) {
			processTradeStatusFinished(tppTradeLog, tpp, notifyEvent);
		} else if (SinaConstant.TRADE_STATUS_PAY_FINISHED.equals(depositStatus)) {
			processTradeStatusPayFinished(tppTradeLog, notifyEvent);
		} else if (SinaConstant.TRADE_STATUS_FAILED.equals(depositStatus)) {
			processTradeStatusFailed(tppTradeLog, tpp, notifyEvent);
		}
		logger.info(MessageFormat.format("++++ 代收订单号{0}代收异步回调成功{1}", outTradeNo, depositStatus));
	}

	private void processTradeStatusFinished(TppTradeLog tppTradeLog, Tpp tpp, CollectionTradeNotifyValueEvent event) throws TaskProcessorException{
		
		String tradeType = tppTradeLog.getTradeType();
		String outTradeNo = event.getOutOrderNo();
		
		if(Summary.AUTO_TENDER.getSummaryType().equals(tradeType)
				|| Summary.TENDER.getSummaryType().equals(tradeType)){
			// do nothing!
			return;
		}
		
		if (tpp == null) {
			logger.info(MessageFormat.format("++++ 等待生成代收订单号{0}关联的支付信息Tpp!", outTradeNo));
			throw new TaskProcessorException(event);
		}
		
		if ((tpp.getStatus() != TppModel.STATUS_SUCEESS)) {
			tpp.setStatus(TppModel.STATUS_SUCEESS);
			tpp.setRespDesc("代收成功");
			tppService.update(tpp);
			logger.info(MessageFormat.format("++++ 代收订单号{0}状态更新为成功!", outTradeNo));
		}
		
	}
	
	private void processTradeStatusPayFinished(TppTradeLog tppTradeLog, CollectionTradeNotifyValueEvent event) throws TaskProcessorException{
		tppTradeLog.setAmount(event.getDepositAmount());
		tppTradeLog.setTradeStatus(event.getDepositStatus());
		tppTradeLog.setTradeTime(DateUtil.getNow());
		tppTradeService.update(tppTradeLog);
		if (SinaConstant.TRADE_CODE_1001.equals(tppTradeLog.getTradeType())) {
			doTender(tppTradeLog);
		} else if (SinaConstant.TRADE_CODE_1002.equals(tppTradeLog.getTradeType())) {
			doRepay(tppTradeLog);
		}
	}
	
	/**
	 * 代收成功投标业务处理
	 */
	private void doTender(TppTradeLog tppTradeLog){
		BorrowModel bm = new BorrowModel();
		String type = tppTradeLog.getServiceType();
		long borrowId = tppTradeLog.getBorrowId();
		String tppUserCustId = tppTradeLog.getTppUserCustId();
		bm.setId(borrowId);
		bm.setBidNo(tppTradeLog.getOrderNo());
		bm.setTenderBilNo(tppTradeLog.getOrderNo());
		bm.setTenderBilDate(DateUtil.dateStr3(tppTradeLog.getTradeTime()));
		// borrowTender的account金额包含现金、红包、体验券
		bm.setMoney(tppTradeLog.getAmount());
		bm.setTppUserCustId(tppUserCustId);

		if (SinaConstant.TRADE_SERVICE_AUTO_TENDER.equals(type)) {
			BorrowValueEvent borrowEvent = new BorrowValueEvent();
			borrowEvent.setBorrowModel(bm);
			borrowEvent.setTaskProcessorClass(TenderAutoTaskProcessor.class);
			QueueHandlers.put(borrowEvent);
		} else if (SinaConstant.TRADE_SERVICE_TENDER.equals(type)) {
			JSONObject merPivJson = JSON.parseObject(tppTradeLog.getMemo());
			long rateInterestId = NumberUtil.getLong(merPivJson.getString("rateId"));
			String redEnvelopeStr = merPivJson.getString("redStr");
			double redEnvelopeMoney = merPivJson.getDoubleValue("redMoney");
			String experStr = merPivJson.getString("experStr");
			double experienceMoney = merPivJson.getDoubleValue("experMoney");
			long userId = NumberUtil.getLong(merPivJson.getString("userId"));
			bm.setUserId(userId);
			bm.setRateInterestId(rateInterestId);
			bm.setRedEnvelopeStr(redEnvelopeStr);
			bm.setTotalRedEnvelopeMoney(redEnvelopeMoney);
			bm.setExperiences((long[]) ConvertUtils.convert(experStr.split(","), long.class));
			bm.setTotalExperienceMoney(experienceMoney);
			BorrowValueEvent borrowEvent = new BorrowValueEvent();
			borrowEvent.setBorrowModel(bm);
			borrowEvent.setTaskProcessorClass(TenderTaskProcessor.class);
			QueueHandlers.put(borrowEvent);
			// 如果 虚拟金（体验金+红包等）代收成功，执行放款
		} else if (SinaConstant.TRADE_SERVICE_VIRTUAL.equals(type)) {
			BorrowValueEvent borrowEvent = new BorrowValueEvent();
			borrowEvent.setBorrowModel(bm);
			borrowEvent.setTaskProcessorClass(VerifyFullSuccessTaskProcessor.class);
			QueueHandlers.put(borrowEvent);
		} else if (SinaConstant.TRADE_SERVICE_RED_ENVELOPE_EXCHAGE.equals(type)) {
			// 现金红包兑换待收成功，执行付款
			tppTradeLog.setTradeType(SinaConstant.TRADE_CODE_2001);
			TppTradeLogValueEvent event = new TppTradeLogValueEvent();
			event.setTppTradeLog(tppTradeLog);
			QueueHandlers.put(event);
		}

	}

	/**
	 * 代收异步回调成功还款处理
	 */
	public void doRepay(TppTradeLog tppTradeLog) {
		long borrowRepaymentId = tppTradeLog.getBorrowRepaymentId();
		BorrowRepayment borrowRepayment = borrowRepaymentService.find(borrowRepaymentId);
		if (borrowRepayment != null) {
			List<TppTradeLog> list = tppTradeService.find(borrowRepaymentId, tppTradeLog.getServiceType(),
					tppTradeLog.getTradeType());
			for (TppTradeLog log : list) {
				if (!SinaConstant.TRADE_STATUS_PAY_FINISHED.equals(log.getTradeStatus())) {
					logger.info("还款前的代收未处理完毕...");
					return;
				}
			}
			borrowService.notifySuccessRepay(borrowRepayment);
		}
	}
	
	private void processTradeStatusFailed(TppTradeLog tppTradeLog, Tpp tpp, CollectionTradeNotifyValueEvent event) throws TaskProcessorException{
		tppTradeLog.setTradeStatus(event.getDepositStatus());
		tppTradeLog.setTradeTime(DateUtil.getNow());
		if (SinaConstant.TRADE_SERVICE_AUTO_TENDER.equals(tppTradeLog.getServiceType())
				|| SinaConstant.TRADE_SERVICE_TENDER.equals(tppTradeLog.getServiceType())) {
			doTenderFail(tppTradeLog, event);
		} else {
			doTppFail(tppTradeLog, tpp, event);
		}
		tppTradeService.update(tppTradeLog);
	}

	/**
	 * 投标失败处理
	 */
	private void doTenderFail(TppTradeLog tppTradeLog, CollectionTradeNotifyValueEvent event) {
		String tenderBilNo = tppTradeLog.getOrderNo();
		BorrowTender borrowTender = borrowTenderService.find(tenderBilNo);
		if(borrowTender == null){
			return;
		}
		
		Borrow borrow = borrowService.find(borrowTender.getBorrow().getId());
		if (BorrowStatus.STATUS_TRIAL_PASSED == borrow.getStatus()) {
			if(borrowTender.getStatus() !=  2) {
				logger.info(MessageFormat.format("++++ 代收订单号{0}投资记录回滚业务处理开始", event.getOutOrderNo()));
				borrowTender.setStatus(BorrowTenderStatus.FAIL);
				borrowTenderService.update(borrowTender);
				double accountYes = BigDecimalUtil.sub(borrow.getAccountYes(), borrowTender.getAccount());
				borrow.setAccountYes(accountYes);
				borrowService.update(borrow);
				// 解冻投标资金
				accountService.unFreeze(borrowTender.getUser().getUserId(), borrow.getUser().getUserId(), borrowTender.getRealAmount());
			} else{
				logger.info(MessageFormat.format("++++ 代收订单号{0}投资记录回滚业务已被处理", event.getOutOrderNo()));
			}
		} else {
			tppTradeLog.setMemo("代收交易结果失败，投资记录回滚失败！");
		}
	}

	/**
	 * 代收代付，异步回调结果中交易状态为失败时,更新调度任务状态为失败
	 * @throws TaskProcessorException 
	 */
	private void doTppFail(TppTradeLog tppTradeLog, Tpp tpp, CollectionTradeNotifyValueEvent event) throws TaskProcessorException {
		if(tpp == null){
			throw new TaskProcessorException(event);
		}
		tpp.setStatus(TppModel.STATUS_FAIL);
		tpp.setRespDesc("代付处理失败");
		tppService.update(tpp);
	}
	
}
